package middleware

import (
	"bytes"
	"gitee.com/igolang/imoney/internal/common/constants"
	"gitee.com/igolang/pkg/xjson"
	"github.com/gin-gonic/gin"
	uuid "github.com/satori/go.uuid"
	"io"
	"net/http"
)

const (
	requestID = "X-RequestId"
	REQUEST   = constants.RouterMiddleRequestKey
)

func Request() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		u := uuid.NewV4()
		ctx.Set(requestID, u.String())
		ctx.Writer.Header().Set(requestID, u.String())
	}
}

// SysRequest 管理后台中间件
// 在post请求，格式为JSON时会消耗内存存储当前body，不建议在高并发中使用，会消耗多内存
func SysRequest() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		// 不建议在高并发中使用，会消耗多内存
		reqAll := make(map[string]any)
		for _, v := range ctx.Params {
			reqAll[v.Key] = v.Value
		}

		for k, v := range ctx.Request.URL.Query() {
			if len(v) > 0 {
				reqAll[k] = v[0]
			} else {
				reqAll[k] = ""
			}
		}

		if ctx.Request.Method == http.MethodPost || ctx.Request.Method == http.MethodPut || ctx.Request.Method == http.MethodDelete {
			reqBody, _ := io.ReadAll(ctx.Request.Body) // reqBody -> []byte
			defer ctx.Request.Body.Close()
			ctx.Request.Body = io.NopCloser(bytes.NewBuffer(reqBody))
			ctx.Set(gin.BodyBytesKey, reqBody)
			if len(reqBody) > 0 {
				var m map[string]any
				if err := xjson.Unmarshal(reqBody, &m); err == nil {
					for k, v := range m {
						reqAll[k] = v
					}
				}
			}
		}

		ctx.Set(REQUEST, reqAll)
	}
}
